import urllib2
from xml.dom import minidom
from datetime import datetime

from Tools import GetValue, Point, ApiError

class Map :
    '''This class contains a cache for squares, 
    you can get a square by GetSquare, if the square already is not in the cache,
    it retrieves a partition from sqwarea API'''
    
    def __init__(self):
        self._squares = {}
        
    def GetSquare(self, x, y):
        '''Return the square in position (x,y)'''
        
        p = Point(x, y)
        
        if p not in self._squares :
            self._GetSquareInPartition(x, y)
        
        return self._squares[p]
    
    def GetAllSquares(self):
        '''Warning : we can miss some squares !'''
        # upper left coordinate
        xUL = 0
        yUL = 0
        width = 1
        height = 1
        
        # when one of the extend* is 0, we do not extend in the given direction (East, West, ...)
        # 20 is an arbitrary value !
        extendE = 20
        extendW = 20
        extendN = 20
        extendS = 20
        
        kk = 0
        
        while extendE>0 or extendN>0 or extendW>0 or extendS>0 :
            kk+=1
            if kk%20 == 0 :
                print "//  %d %d %d %d  /  (%d,%d) - (%d,%d)" % (extendE, extendW, extendN, extendS, xUL, yUL, width, height)
                
            if extendE > 0 :
                extendE -= 1
                width += 1
                for i in range(height) :
                    if self.GetSquare(xUL+width-1, yUL+i).king != 0 :
                        extendE = 20
                        
            if extendW > 0 :
                extendW -= 1
                xUL -= 1
                width += 1
                for i in range(height) :
                    if self.GetSquare(xUL, yUL+i).king != 0 :
                        extendW = 20
                        
            if extendN > 0 :
                extendN -= 1
                yUL -= 1
                height += 1
                for i in range(width) :
                    if self.GetSquare(xUL+i, yUL).king != 0 :
                        extendN = 20
                        
            if extendS > 0 :
                extendS -= 1
                height += 1
                for i in range(width) :
                    if self.GetSquare(xUL+i, yUL+height-1).king != 0 :
                        extendS = 20
        
        self.xUL = xUL
        self.yUL = yUL
        self.width = width
        self.height = height
    
    def _GetSquareInPartition(self, x, y):
        (xP, yP) = self._GetPartition(x, y)
        self._GetSquares(xP*20, yP*20, 20, 20)
    
    def _GetPartition(self, x, y):
        return (int(x)/20, int(y)/20)
    
    def _GetSquares(self, x, y, width, height):
        print "GetSquares : %d, %d, %d, %d - " % (x,y,width, height),
        t = datetime.now()
        
        f = urllib2.urlopen('http://sqwareaapi.cloudapp.net/map/%d_%d/%d_%d' % (x, x+width-1, y, y+height-1))
        
        print (datetime.now() - t), " - ",
        
        rep = minidom.parse(f)
        
        xmlElt = rep.getElementsByTagName("squares")
        if len(xmlElt)!=1 :
            raise ApiError("Map API error")
            
        xmlElt = xmlElt[0].getElementsByTagName("square")
        if len(xmlElt)==0 :
            raise ApiError("Map API error")
        
        for xE in xmlElt :
            s = Square()
            s.FromXml(xE)
            self._squares[Point(s.x, s.y)] = s
            
        print (datetime.now() - t)
        
            
class Square :
    def __init__(self):
        self.x = None
        self.y = None
        self.king = None
        
    def FromXml(self, xmlElement):
        self.x = int(GetValue(xmlElement.getElementsByTagName("x")[0]))
        self.y = int(GetValue(xmlElement.getElementsByTagName("y")[0]))
        self.king = int(GetValue(xmlElement.getElementsByTagName("king")[0]))